/*
 * Copyright (C) 2009 2DAI
 *
 * Este programa es Software Libre; usted puede redistribuirlo
 * y/o modificarlo bajo los términos de la "GNU General Public
 * License" como lo publica la "FSF Free Software Foundation",
 * o (a su elección) de cualquier versión posterior.
 *
 * Este programa es distribuido con la esperanza de que le será
 * útil, pero SIN NINGUNA GARANTIA; incluso sin la garantía
 * implícita por el MERCADEO o EJERCICIO DE ALGUN PROPOSITO en
 * particular. Vea la "GNU General Public License" para más
 * detalles.
 *
 * Usted debe haber recibido una copia de la "GNU General Public
 * License" junto con este programa, si no, escriba a la "FSF
 * Free Software Foundation, Inc.", 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 */
package logic;

import data.DataManager;
import gui.AbsFrame;
import gui.MainWindow;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.SwingWorker;
import util.AudioPlayer;
import util.Errors;

/**
 * Author: Jorge Garrido Oval
 * Esta es la clase que maneja el funcionamiento de todas las ventanas de
 * mantenimientos.
 */
public class AbsFrameLogic extends SwingWorker<Void, Void> implements ActionListener {

    //Atributos
    private AbsFrame ap;
    private DataManager dm;
    private MainWindow mw;
    private ContentiPanel pa;
    private boolean nuevoRegistro;
    private int opcion;
    //En este array se pondran todas las clases derivadas de DataManager que
    //deban usar esta logica, con el mismo orden que se numeran en la ventana principal
    private String[] dml = {"DataLocals", "DataClubs", "DataPlayers", "DataTeam", "DataReferee", "DataClubRepresentatives", "DataActofProtested"};
    //En este array se pondran todos los paneles que deban usar esta logica,
    //con el mismo orden que se numeran en la ventana principal
    private String[] pal = {"MaintLocals", "MaintClub", "MaintPlayers", "MaintTeam", "MaintReferee", "MaintClubRepresentatives", "MaintActofprotested"};


    //Constructores
    public AbsFrameLogic() {
        dm = null;
        ap = new AbsFrame(this);
        ap.setBounds(0, 0, 570, 450);
        ap.setVisible(true);
    }

    public AbsFrameLogic(int opcion, MainWindow mw, String titulo) {
        this();
        this.mw = mw;
        this.mw.getJDPescritorio().add(this.ap);
        this.opcion = opcion;
        ap.setTitle(titulo);
        ap.enableAnteriores(false);
    }

    //Métodos
    /**
     * Uso de la característica de reflexión de Java.
     * Se llaman a las clases para instanciarlas de forma dinámica llamandolas
     * por su nombre, esta funcion se realiza una cuando las clases ya estan
     * compiladas, en tiempo de ejecucion. Con esto evitamos un switch o una
     * batería de If's que ralentizarian el programa.
     * Tened en cuenta que newInstance() siempre llama al constructor vacio.
     * @param opcion
     */
    private void seleccionaPanel(int opcion) {
        try {
            pa = (ContentiPanel) Class.forName("gui." + pal[opcion]).newInstance();
            ap.add(pa);
            ap.revalidate();
            dm = (DataManager) Class.forName("data." + dml[opcion]).newInstance();
        } catch (InstantiationException ex) {
            Errors.creaError("ERROR: No se ha podido instanciar clase derivada " +
                    "de DataManager/JPanel\n" + ex.getMessage(), ex.getStackTrace());
        } catch (IllegalAccessException ex) {
            Errors.creaError("ERROR: No se ha podido acceder a la clase derivada " +
                    "de DataManager/JPanel\n" + ex.getMessage(), ex.getStackTrace());
        } catch (ClassNotFoundException ex) {
            Errors.creaError("ERROR: No existe se encuentra la clase derivada " +
                    "de DataManager/JPanel\n" + ex.getMessage(), ex.getStackTrace());
        }

    }

    /**
     * Método usado para el funcionamiento de la botonera
     * @param e
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Primero")) {
            if (!(0 == dm.index)) {
                pa.setContenido(dm.primero());
                ap.enableAnteriores(false);
            }else{
                ap.enableAnteriores(false);
            }
            ap.enableSiguientes(true);
        } else if (e.getActionCommand().equals("Anterior")) {
            if (!(0 == dm.index)) {
                pa.setContenido(dm.anterior());
                ap.enableAnteriores(true);
            }else{
                ap.enableAnteriores(false);
            }
            ap.enableSiguientes(true);
        } else if (e.getActionCommand().equals("Siguiente")) {
            if (!(dm.getList().size()-1 == dm.index)) {
                pa.setContenido(dm.siguiente());
                ap.enableSiguientes(true);
            }else{
                ap.enableSiguientes(false);
            }
            ap.enableAnteriores(true);
        } else if (e.getActionCommand().equals("Ultimo")) {
            if (!(dm.getList().size()-1 == dm.index)) {
                pa.setContenido(dm.ultimo());
                ap.enableSiguientes(false);
            }else{
                ap.enableSiguientes(false);
            }
            ap.enableAnteriores(true);
        } else if (e.getActionCommand().equals("Nuevo")) {
            nuevoRegistro = true;
            ap.botonesEdit(false);
            pa.enableTextFields(true);
            pa.clearTextFields();
        } else if (e.getActionCommand().equals("Editar")) {
            nuevoRegistro = false;
            ap.botonesEdit(false);
            pa.enableTextFields(true);
        } else if (e.getActionCommand().equals("Eliminar")) {
            dm.eliminar(pa.getContenido());
            pa.setContenido(dm.anterior());
        } else if (e.getActionCommand().equals("Guardar")) {
            if (nuevoRegistro)
                dm.insertar(pa.getContenido());
            else
                dm.guardar(pa.getContenido());
            pa.setContenido(dm.siguiente());
            pa.enableTextFields(false);
            ap.botonesEdit(true);
        } else if (e.getActionCommand().equals("Cancelar")) {
            ap.botonesEdit(true);
            pa.enableTextFields(false);
            pa.setContenido(dm.anterior());
        }
        ap.revalidate();
    }

    /**
     * Este método hace que las ventanas vibren
     */
    private void vibrar() {
            final int originalX = ap.getX();
            final int originalY = ap.getY();
            try {
                for (int i = 0; i < 5; i++) {
                    Thread.sleep(10);
                    ap.setLocation(ap.getX(), ap.getY() + 5);
                    Thread.sleep(10);
                    ap.setLocation(ap.getX(), ap.getY() - 5);
                    Thread.sleep(10);
                    ap.setLocation(ap.getX() - 5, ap.getY());
                    Thread.sleep(10);
                    ap.setLocation(originalX, originalY);
                }
            } catch (Exception ex) {
                Errors.creaAdvertencia("La posisción no es correcta, la ventana no vibrará.", ex.getStackTrace());
            }
        }

    @Override
    protected Void doInBackground() throws Exception {
        setProgress(50);
        seleccionaPanel(opcion);
        pa.setContenido(dm.primero());
        pa.enableTextFields(false);
        setProgress(100);
        new AudioPlayer(System.getProperty("user.dir")+"/src/audio/zumbido.wav").start();
        vibrar();
        return null;
    }
}
